package com.icebartech.base.modules.common.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.icebartech.base.modules.common.dto.DictDTO;
import com.icebartech.base.modules.common.mapper.SysCodeMapper;
import com.icebartech.base.modules.common.model.SysCode;
import com.icebartech.base.modules.common.service.SysCodeService;
import com.icebartech.core.components.RedisComponent;
import com.icebartech.core.constants.IcebartechConstants;
import com.icebartech.core.modules.AbstractService;
import com.icebartech.core.modules.BaseMapper;

@Service
public class SysCodeServiceImpl extends AbstractService implements SysCodeService {
	
	@Autowired
	private SysCodeMapper sysCodeMapper;
	
	@Autowired
	private RedisComponent redisComponent;

	@Override
	public BaseMapper getBaseMapper() {
		return this.sysCodeMapper;
	}

	
	@Override
	public List<SysCode> findSysCodeByType(String codeType) {
		SysCode sysCode = new SysCode();
		sysCode.setCodeType(codeType);
		return this.findByList(sysCode);
	}
	
	@Override
	public SysCode findSysCodeByCodeId(String codeType, Long codeId) {
		SysCode record = new SysCode();
		record.setCodeType(codeType);
		record.setCodeId(codeId);
		List<SysCode> dataList = this.findByList(record);
		if(CollectionUtils.isNotEmpty(dataList)){
			return dataList.get(0);
		}
		return null;
	}
	
	@Override
	public List<SysCode> findSysCodeByParentCode(String codeType, Long parentCode) {
		SysCode record = new SysCode();
		record.setCodeType(codeType);
		record.setParentCode(parentCode);
		return this.findByList(record);
	}

	@Override
	public SysCode findSysCodeByCodeName(String codeType, String codeName) {
		SysCode record = new SysCode();
		record.setCodeType(codeType);
		record.setCodeName(codeName);
		List<SysCode> dataList = this.findByList(record);
		if(CollectionUtils.isNotEmpty(dataList)){
			return dataList.get(0);
		}
		return null;
	}
	
	@Override
	public List<DictDTO> loadCityDict() {
		String json = redisComponent.getRedisCache(IcebartechConstants.SYSTEM_DICTIONARY_GROUP_KEY, "province");
		if(StringUtils.isNotEmpty(json)){
			List<DictDTO> list = JSON.parseArray(json, DictDTO.class);
			if(CollectionUtils.isNotEmpty(list)){
				return list;
			}
		}
		//加载省份等
		List<SysCode> provinceList = findSysCodeByType("province");
		List<DictDTO> provinceDTOList = new ArrayList<>();
		if(CollectionUtils.isNotEmpty(provinceList)){
			for(SysCode sysCode : provinceList){
				DictDTO provinceDTO = new DictDTO();
				provinceDTO.setKey(sysCode.getCodeId().toString());
				provinceDTO.setValue(sysCode.getCodeName());
				
				//加载城市
				List<SysCode> cityList = findSysCodeByParentCode("city", sysCode.getCodeId());
				List<DictDTO> cityDTOList = new ArrayList<>();
				if(CollectionUtils.isNotEmpty(cityList)){
					for(SysCode citySysCode : cityList){
						DictDTO cityDTO = new DictDTO();
						cityDTO.setKey(citySysCode.getCodeId().toString());
						cityDTO.setValue(citySysCode.getCodeName());
						
						//加载地区
						List<SysCode> districtList = findSysCodeByParentCode("district", citySysCode.getCodeId());
						List<DictDTO> districtDTOList = new ArrayList<>();
						if(CollectionUtils.isNotEmpty(districtList)){
							for(SysCode districtSysCode : districtList){
								DictDTO districtDTO = new DictDTO();
								districtDTO.setKey(districtSysCode.getCodeId().toString());
								districtDTO.setValue( districtSysCode.getCodeName());
								districtDTOList.add(districtDTO);
							}
						}
						cityDTO.setChilds(districtDTOList);
						cityDTOList.add(cityDTO);
					}
				}
				provinceDTO.setChilds(cityDTOList);
				provinceDTOList.add(provinceDTO);
			}
		}
		redisComponent.putRedisCache(IcebartechConstants.SYSTEM_DICTIONARY_GROUP_KEY, "province", JSON.toJSONString(provinceDTOList));
		return provinceDTOList;
	}
	
	@Override
	public List<DictDTO> findDictByType(String codeType) {
		if(codeType.equals("province")) {
			return loadCityDict();
		}
		List<SysCode> codeList = findSysCodeByType(codeType);
		List<DictDTO> dataList = new ArrayList<>();
		if(CollectionUtils.isNotEmpty(codeList)){
			codeList.forEach(e -> {
				DictDTO dto = findDictByRecycle(e.getCodeType(), e.getCodeId());
				dataList.add(dto);
			});
		}
		return dataList;
	}
	
	
	/**
	 * 递归获取某个类型的字典树型结构
	 * @param codeType 字典类型
	 * @param codeId 字典id
	 * @return
	 */
	private DictDTO findDictByRecycle(String codeType, Long codeId) {
		SysCode sysCode = findSysCodeByCodeId(codeType, codeId);
		if(sysCode != null) {
			DictDTO dictDTO = new DictDTO();
			dictDTO.setKey(sysCode.getCodeId().toString());
			dictDTO.setValue(sysCode.getCodeName());
			List<SysCode> childList = findSysCodeByParentCode(sysCode.getCodeId());
			List<DictDTO> childs = new ArrayList<>();
			if(CollectionUtils.isNotEmpty(childList)) {
				for(SysCode code : childList) {
					DictDTO tempDTO = findDictByRecycle(code.getCodeType(), code.getCodeId());
					childs.add(tempDTO);
				}
			}
			if(CollectionUtils.isNotEmpty(childs)) {
				dictDTO.setChilds(childs);
			}
			return dictDTO;
		}
		return null;
	}
	
	public List<SysCode> findSysCodeByParentCode(Long parentCode) {
		SysCode record = new SysCode();
		record.setParentCode(parentCode);
		return this.findByList(record);
	}
	
}
